/*
 * Copyright (C) 2008, Velocityme Partnership
 * SprintActions.java
 *
 * Created on 28 August 2008, 20:40
 */

package com.velocityme.www.interfaces.nodeactions;

import com.velocityme.entity.PermissionBean;
import com.velocityme.interfaces.*;
import com.velocityme.utility.DurationRemaining;
import com.velocityme.utility.TimeSummaryTable;
import com.velocityme.valueobjects.*;
import com.velocityme.www.actionforms.NodeIdActionForm;
import com.velocityme.www.actionforms.nodeactionforms.ActionValueActionForm;
import com.velocityme.www.actionforms.nodeactionforms.SprintValueActionForm;
import com.velocityme.www.dto.BurnDownDTO;
import com.velocityme.www.dto.IntegerString;
import com.velocityme.www.dto.PersonTimeDTO;
import com.velocityme.www.dto.ProgressDTO;
import com.velocityme.www.dto.TimeReportDTO;
import com.velocityme.www.interfaces.ShowNodeAction;
import com.velocityme.www.utility.NodeUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.*;
import javax.swing.tree.TreeModel;

import org.apache.struts.action.*;
import org.apache.struts.actions.DispatchAction;

/**
 *
 * @author  Robert
 */
public class SprintActions extends NodeActions {
    
    /** Creates a new instance of SprintActions */
    public SprintActions() {
    }
    
    public ActionForward show(ActionMapping mapping, 
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        SprintPK sprintPK = new SprintPK(nodePK.getNodeId());
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        session.setAttribute("sprintValue", cs.getSprintValue(key, sprintPK));
        session.setAttribute("teamValues", cs.getSprintTeamPersonValues(key, sprintPK));
        Collection progressDTOs = calculateProgressDTOs(key, cs.getSprintProgressSum(key, sprintPK));
        session.setAttribute("progressValue", progressDTOs);
        session.setAttribute("total", calculateMax(progressDTOs));
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    public ActionForward showCreate(ActionMapping mapping, 
                                    ActionForm form,
                                    HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        SprintPK sprintPK = new SprintPK(nodePK.getNodeId());
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        session.setAttribute("parentNodePK", nodePK);
        session.setAttribute("allPersonPairs", NodeUtil.getAllPersonPairs(key, cs));
        session.setAttribute("teamPersonPairs", new ArrayList());
        SprintValueActionForm sprintValueActionForm = new SprintValueActionForm();
        sprintValueActionForm.setScrumMasterId(key.getPersonPK().getPersonId());
        Calendar now = Calendar.getInstance();
        sprintValueActionForm.setStartYear(now.get(Calendar.YEAR));
        sprintValueActionForm.setStartMonth(now.get(Calendar.MONTH));
        sprintValueActionForm.setStartDay(now.get(Calendar.DATE));
        sprintValueActionForm.setStopYear(now.get(Calendar.YEAR));
        sprintValueActionForm.setStopMonth(now.get(Calendar.MONTH));
        sprintValueActionForm.setStopDay(now.get(Calendar.DATE));
        session.setAttribute("sprintActionForm", sprintValueActionForm);
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        SprintValue sprintValue = new SprintValue();
        sprintValue.setNodeValue(new NodeValue());
        session.setAttribute("sprintValue", sprintValue);
        return mapping.findForward("ACTION_EDIT");
    }
    
    public ActionForward showEdit(ActionMapping mapping, 
                                  ActionForm form,
                                  HttpServletRequest request,
                                  HttpServletResponse response) throws Exception {
        NodePK nodePK = (NodePK)request.getAttribute("nodePK");
        SprintPK sprintPK = new SprintPK(nodePK.getNodeId());
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        SprintValue sprintValue = cs.getSprintValue(key, sprintPK);
        session.setAttribute("sprintValue", sprintValue);
        SprintValueActionForm sprintValueActionForm = new SprintValueActionForm();
        sprintValueActionForm.setName(sprintValue.getNodeValue().getName());
        sprintValueActionForm.setDescription(sprintValue.getNodeValue().getDescription());
        sprintValueActionForm.setScrumMasterId(sprintValue.getScrumMasterValue().getPersonId());
        Collection teamPersonIntegerStrings = new ArrayList();
        Iterator i = cs.getSprintTeamPersonValues(key, sprintPK).iterator();
        while(i.hasNext()) {
            PersonValue personValue = (PersonValue)i.next();
            teamPersonIntegerStrings.add(new IntegerString(personValue.getPersonId(), new PersonValueToString(personValue).toString()));
        }
        Calendar date = Calendar.getInstance();
        date.setTime(sprintValue.getStartDate());
        sprintValueActionForm.setStartYear(date.get(Calendar.YEAR));
        sprintValueActionForm.setStartMonth(date.get(Calendar.MONTH));
        sprintValueActionForm.setStartDay(date.get(Calendar.DATE));
        date.setTime(sprintValue.getStopDate());
        sprintValueActionForm.setStopYear(date.get(Calendar.YEAR));
        sprintValueActionForm.setStopMonth(date.get(Calendar.MONTH));
        sprintValueActionForm.setStopDay(date.get(Calendar.DATE));
        session.setAttribute("teamPersonPairs", teamPersonIntegerStrings);
        session.setAttribute("sprintActionForm", sprintValueActionForm);
        session.setAttribute("years", NodeUtil.getInstance().getYears());
        session.setAttribute("months", NodeUtil.getInstance().getMonths());
        session.setAttribute("days", NodeUtil.getInstance().getDays());
        session.setAttribute("allPersonPairs", NodeUtil.getAllPersonPairs(key, cs));
        return mapping.findForward("ACTION_EDIT");
    }
    
    public ActionForward edit(ActionMapping mapping, 
                              ActionForm form,
                              HttpServletRequest request,
                              HttpServletResponse response) throws Exception {
        HttpSession session = request.getSession();
        KeySession key = (KeySession)session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        NodePK nodePK;
        if (request.getParameter("btnSubmit").equals("OK")) {
            SprintValue sprintValue = (SprintValue)session.getAttribute("sprintValue");
            SprintValueActionForm sprintValueActionForm = (SprintValueActionForm)form;
            sprintValue.getNodeValue().setName(sprintValueActionForm.getName());
            sprintValue.getNodeValue().setDescription(sprintValueActionForm.getDescription());
            Calendar startDate = Calendar.getInstance(); startDate.clear();
            startDate.set(sprintValueActionForm.getStartYear(), sprintValueActionForm.getStartMonth(), sprintValueActionForm.getStartDay());
            sprintValue.setStartDate(startDate.getTime());
            Calendar stopDate = Calendar.getInstance(); stopDate.clear();
            stopDate.set(sprintValueActionForm.getStopYear(), sprintValueActionForm.getStopMonth(), sprintValueActionForm.getStopDay(), 23, 59, 59);
            sprintValue.setStopDate(stopDate.getTime());
            PersonValue scrumMasterPersonValue = new PersonValue();
            scrumMasterPersonValue.setPrimaryKey(new PersonPK(sprintValueActionForm.getScrumMasterId()));
            sprintValue.setScrumMasterValue(scrumMasterPersonValue);
            SprintPK sprintPK;
            if (sprintValue.sprintIdHasBeenSet()) {
                sprintPK = sprintValue.getPrimaryKey();
                cs.sprintEdit(key, sprintPK, sprintValue, sprintValueActionForm.getTeamPersonPKs());
            }
            else {
                ActionErrors errors = new ActionErrors();
                NodePK parentNodePK = (NodePK)session.getAttribute("parentNodePK");
                sprintPK = cs.sprintCreate(key, parentNodePK, sprintValue, sprintValueActionForm.getTeamPersonPKs());
            }
            nodePK = new NodePK(sprintPK.getSprintId());
        }
        // Cancel simply displays the original node again
        else {
            nodePK = new NodePK((Integer)session.getAttribute("nodeId"));
        }
        request.setAttribute("nodePK", nodePK);
        return mapping.findForward("ACTION_SUCCESS");
    }
    
    public ActionForward showBurnDown(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        NodePK nodePK = (NodePK) request.getAttribute("nodePK");
        HttpSession session = request.getSession();
        KeySession key = (KeySession) session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        NodeValue nodeValue = cs.getNodeValue(key, nodePK);
        ShowNodeAction.setupTreeDisplay(session, nodeValue, "BurnDown");
        SprintPK sprintPK = new SprintPK(nodePK.getNodeId());
        Map durations = cs.getSprintDurationSum(key, sprintPK);
        Collection burnDownDTOs = TaskActions.calculateBurnDownDTOs(durations);
        session.setAttribute("burnDownValue", burnDownDTOs);
        session.setAttribute("total", TaskActions.calculateMax(burnDownDTOs));
        return mapping.findForward("ACTION_DISPLAY");
    }
    
    private ActionForward showTimeReportTemplate(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response, String tab)
            throws Exception {
        NodePK nodePK = (NodePK) request.getAttribute("nodePK");
        HttpSession session = request.getSession();
        KeySession key = (KeySession) session.getAttribute("sessionKey");
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        NodeValue nodeValue = cs.getNodeValue(key, nodePK);
        ShowNodeAction.setupTreeDisplay(session, nodeValue, tab);
        SprintPK sprintPK = new SprintPK(nodePK.getNodeId());
        SprintValue sprintValue = cs.getSprintValue(key, sprintPK);
        Map results;
        if (tab.equals("Time Report"))
            results = cs.getSprintSearchTimeLogValue(key, sprintPK);
        else
            results = cs.getSprintUnplannedSearchTimeLogValue(key, sprintPK);
        TimeReportDTO timeReportDTO = new TimeReportDTO("/",
                                                        sprintValue.getStartDate(),
                                                        sprintValue.getStopDate(),
                                                        new Date(),
                                                        (Collection)results.get("Entries"),
                                                        (Collection)results.get("Names"),
                                                        (Collection)results.get("Summaries"));
        session.setAttribute("timeReportDTO", timeReportDTO);
        Iterator i = ((Collection)results.get("Names")).iterator();
        TimeSummaryTable t = (TimeSummaryTable)((List)results.get("Summaries")).get(0);
        List personTimeDTO = new ArrayList();
        if (t.getRows().size() > 0) {
            TimeSummaryTable.Row row = (TimeSummaryTable.Row)(((List)t.getRows()).get(0));
            for (int j = 0; j < row.getLongPercents().length - 1; j++) {
                String name = (String)i.next();
                long duration = row.getLongPercents()[j].getLong();
                int percent = (int)(duration * 100L / t.getMax());
                personTimeDTO.add(new PersonTimeDTO(duration, name, percent));
            }
        }
        session.setAttribute("personTimeDTO", personTimeDTO);
        return mapping.findForward("ACTION_DISPLAY");
    }

    public ActionForward showTimeReport(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        return showTimeReportTemplate(mapping, form, request, response, "Time Report");
    }
    
    public ActionForward showUnplannedReport(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        return showTimeReportTemplate(mapping, form, request, response, "Unplanned");
    }
    
    static public Collection calculateProgressDTOs(KeySession key, Map progress) throws Exception {
        Collection progressDTOs = new ArrayList();
        RemoteClientSession cs = RemoteClientSessionUtil.getHome().create();
        Iterator i = progress.keySet().iterator();
        while (i.hasNext()) {
            TaskValue taskValue = (TaskValue)i.next();
            String taskName = cs.getProjectPathName(key, taskValue.getPrimaryKey());
            DurationRemaining dr = (DurationRemaining)progress.get(taskValue);
            int duration_min = dr.getDuration_min();
            int remaining_min = dr.getRemaining_min();
            progressDTOs.add(new ProgressDTO(taskName, taskValue, duration_min, remaining_min));
        }
        return progressDTOs;
    }
    
    static public Integer calculateMax(Collection progressDTOs) {
        Iterator i = progressDTOs.iterator();
        int total = 0;
        while (i.hasNext()) {
            ProgressDTO bd = (ProgressDTO)i.next();
            total = Math.max(total, bd.getDuration_min() + bd.getRemaining_min());
        }
        return new Integer(total);
    }
    
}
